syntax = "proto3";

package kuma.mesh.v1alpha1;

option go_package = "github.com/kumahq/kuma/api/mesh/v1alpha1";

import "api/mesh/options.proto";
import "api/mesh/v1alpha1/selector.proto";

import "google/protobuf/duration.proto";
import "google/protobuf/wrappers.proto";
import "validate/validate.proto";
import "kuma-doc/config.proto";

option (doc.config) = {
  type : Policy,
  name : "RateLimit",
  file_name : "rate-limit"
};

message RateLimit {

  option (kuma.mesh.resource).name = "RateLimitResource";
  option (kuma.mesh.resource).type = "RateLimit";
  option (kuma.mesh.resource).package = "mesh";
  option (kuma.mesh.resource).kds.send_to_zone = true;
  option (kuma.mesh.resource).ws.name = "rate-limit";
  option (kuma.mesh.resource).allow_to_inspect = true;

  // List of selectors to match dataplanes that rate limit will be applied for
  repeated Selector sources = 1
      [ (validate.rules).repeated .min_items = 1, (doc.required) = true ];

  // List of selectors to match services that need to be rate limited.
  repeated Selector destinations = 2
      [ (validate.rules).repeated .min_items = 1, (doc.required) = true ];

  message Conf {
    message Http {
      // The number of HTTP requests this RateLimiter allows
      // +required
      uint32 requests = 1 [ (doc.required) = true ];

      // The the interval for which `requests` will be accounted.
      // +required
      google.protobuf.Duration interval = 2 [ (doc.required) = true ];

      message OnRateLimit {
        // The HTTP status code to be set on a RateLimit event
        // +optional
        google.protobuf.UInt32Value status = 1;

        message HeaderValue {
          // Header name
          // +optional
          string key = 1;
          // Header value
          // +optional
          string value = 2;

          // Should the header be appended
          // +optional
          google.protobuf.BoolValue append = 3;
        }

        // The Headers to be added to the HTTP response on a RateLimit event
        // +optional
        repeated HeaderValue headers = 3;
      }

      // Describes the actions to take on RatelLimiter event
      // +optional
      OnRateLimit onRateLimit = 3;
    }

    // The HTTP RateLimit configuration
    // +optional
    Http http = 1;
  }

  // Configuration for RateLimit
  // +required
  Conf conf = 3 [ (doc.required) = true ];
}
